home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / editors / pur_c_vi.zoo / normal.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-08-11  |  8.2 KB  |  414 lines

  1. /*
  2.  * STevie - ST editor for VI enthusiasts.    ...Tim Thompson...twitch!tjt...
  3.  */
  4.  
  5. #include <ctype.h>
  6. #include "stevie.h"
  7.  
  8. /*
  9.  * normal
  10.  *
  11.  * Execute a command in normal mode.
  12.  */
  13.  
  14. normal(c)
  15. int c;
  16. {
  17.     char *p, *q;
  18.     int nchar, n;
  19.  
  20.     switch(c){
  21.     case 'H':
  22.         help();
  23.         /* fall through purposely */
  24.     case '\014':
  25.         screenclear();
  26.         updatescreen();
  27.         break;
  28.     case 04:
  29.         /* control-d */
  30.         if ( ! onedown(10) )
  31.             beep();
  32.         break;
  33.     case  025:
  34.         /* control-u */
  35.         if ( ! oneup(10) )
  36.             beep();
  37.         break;
  38.     case 06:
  39.         /* control-f */
  40.         if ( ! onedown(Rows) )
  41.             beep();
  42.         break;
  43.     case 02:
  44.         /* control-b */
  45.         if ( ! oneup(Rows) )
  46.             beep();
  47.         break;
  48.     case '\007':
  49.         fileinfo();
  50.         break;
  51.     case 'G':
  52.         gotoline(Prenum);
  53.         break;
  54.     case 'l':
  55.         if ( ! oneright() )
  56.             beep();
  57.         break;
  58.     case 'h':
  59.         if ( ! oneleft() )
  60.             beep();
  61.         break;
  62.     case 'k':
  63.         if ( ! oneup(1) )
  64.             beep();
  65.         break;
  66.     case 'j':
  67.         if ( ! onedown(1) )
  68.             beep();
  69.         break;
  70.     case 'b':
  71.         /* If we're on the first character of a word, force */
  72.         /* an initial backup. */
  73.         if ( ! issepchar(*Curschar) && Curschar>Filemem
  74.             && issepchar(*(Curschar-1)) )
  75.             Curschar--;
  76.  
  77.         if ( ! issepchar(*Curschar) ) {
  78.             /* If we start in the middle of a word, back */
  79.             /* up until we hit a separator. */
  80.             while ( Curschar>Filemem && !issepchar(*Curschar))
  81.                 Curschar--;
  82.             if ( issepchar(*Curschar) )
  83.                 Curschar++;
  84.         }
  85.         else {
  86.             /* back up past all separators. */
  87.             while ( Curschar>Filemem && issepchar(*Curschar))
  88.                 Curschar--;
  89.             /* back up past all non-separators. */
  90.             while (Curschar>Filemem && !issepchar(*Curschar)){
  91.                 Curschar--;
  92.             }
  93.             if ( issepchar(*Curschar) )
  94.                 Curschar++;
  95.         }
  96.         break;
  97.     case 'w':
  98.         if ( issepchar(*Curschar) ) {
  99.             /* If we're on a separator, we advance to */
  100.             /* the next non-separator char. */
  101.             while ( (p=Curschar+1) < Fileend ) {
  102.                 Curschar = p;
  103.                 if ( ! issepchar(*Curschar) )
  104.                     break;
  105.             }
  106.         }
  107.         else {
  108.             /* If we're in the middle of a word, we */
  109.             /* advance to the next word-separator. */
  110.             while ( (p=Curschar+1) < Fileend ) {
  111.                 Curschar = p;
  112.                 if ( issepchar(*Curschar) )
  113.                     break;
  114.             }
  115.             /* Now go past any trailing white space */
  116.             while (isspace(*Curschar) && (Curschar+1)<Fileend)
  117.                 Curschar++;
  118.         }
  119.         break;
  120.     case '$':
  121.         while ( oneright() )
  122.             ;
  123.         break;
  124.     case '0':
  125.     case '^':
  126.         beginline();
  127.         break;
  128.     case 'x':
  129.         /* Can't do it if we're on a blank line.  (Actually it */
  130.         /* does work, but we want to match the real 'vi'...) */
  131.         if ( *Curschar == '\n' )
  132.             beep();
  133.         else {
  134.             addtobuff(Redobuff,'x',NULL);
  135.             /* To undo it, we insert the same character back. */
  136.             resetundo();
  137.             addtobuff(Undobuff,'i',*Curschar,'\033',NULL);
  138.             Uncurschar = Curschar;
  139.             delchar();
  140.             updatescreen();
  141.         }
  142.         break;
  143.     case 'a':
  144.         /* Works just like an 'i'nsert on the next character. */
  145.         if ( Curschar < (Fileend-1) )
  146.             Curschar++;
  147.         resetundo();
  148.         startinsert("a");
  149.         break;
  150.     case 'i':
  151.         resetundo();
  152.         startinsert("i");
  153.         break;
  154.     case 'o':
  155.         opencmd();
  156.         updatescreen();
  157.         resetundo();
  158.         startinsert("o");
  159.         break;
  160.     case 'd':
  161.         nchar = vgetc();
  162.         n = (Prenum==0?1:Prenum);
  163.         switch(nchar){
  164.         case 'd':
  165.             sprintf(Redobuff,"%ddd",n);
  166.             /* addtobuff(Redobuff,'d','d',NULL); */
  167.             beginline();
  168.             resetundo();
  169.             Uncurschar = Curschar;
  170.             yankline(n);
  171.             delline(n);
  172.             beginline();
  173.             updatescreen();
  174.             /* If we have backed xyzzy, then we deleted the */
  175.             /* last line(s) in the file. */
  176.             if ( Curschar < Uncurschar ) {
  177.                 Uncurschar = Curschar;
  178.                 nchar = 'p';
  179.             }
  180.             else
  181.                 nchar = 'P';
  182.             addtobuff(Undobuff,nchar,NULL);
  183.             break;
  184.         case 'w':
  185.             addtobuff(Redobuff,'d','w',NULL);
  186.             resetundo();
  187.             delword(1);
  188.             Uncurschar = Curschar;
  189.             updatescreen();
  190.             break;
  191.         }
  192.         break;
  193.     case 'c':
  194.         nchar = vgetc();
  195.         switch(nchar){
  196.         case 'c':
  197.             resetundo();
  198.             /* Go to the beginning of the line */
  199.             beginline();
  200.             yankline(1);
  201.             /* delete everything but the newline */
  202.             while ( *Curschar != '\n' )
  203.                 delchar();
  204.             startinsert("cc");
  205.             updatescreen();
  206.             break;
  207.         case 'w':
  208.             resetundo();
  209.             delword(0);
  210.             startinsert("cw");
  211.             updatescreen();
  212.             break;
  213.         }
  214.         break;
  215.     case 'y':
  216.         nchar = vgetc();
  217.         switch(nchar){
  218.         case 'y':
  219.             yankline(Prenum==0?1:Prenum);
  220.             break;
  221.         default:
  222.             beep();
  223.         }
  224.         break;
  225.     case '>':
  226.         nchar = vgetc();
  227.         n = (Prenum==0?1:Prenum);
  228.         switch(nchar){
  229.         case '>':
  230.             tabinout(0,n);
  231.             updatescreen();
  232.             break;
  233.         default:
  234.             beep();
  235.         }
  236.         break;
  237.     case '<':
  238.         nchar = vgetc();
  239.         n = (Prenum==0?1:Prenum);
  240.         switch(nchar){
  241.         case '<':
  242.             tabinout(1,n);
  243.             updatescreen();
  244.             break;
  245.         default:
  246.             beep();
  247.         }
  248.         break;
  249.     case '?':
  250.     case '/':
  251.     case ':':
  252.         readcmdline(c);
  253.         break;
  254.     case 'n':
  255.         repsearch();
  256.         break;
  257.     case 'C':
  258.     case 'D':
  259.         p = Curschar;
  260.         while ( Curschar >= p )
  261.             delchar();
  262.         updatescreen();
  263.         resetundo();    /* This should really go above the */
  264.                 /* delchars above, and the undobuff should */
  265.                 /* be constructed by them. */
  266.         if ( c == 'C' ) {
  267.             Curschar++;
  268.             startinsert("C");
  269.         }
  270.         break;
  271.     case 'r':
  272.         nchar = vgetc();
  273.         resetundo();
  274.         if ( nchar=='\n' || (!Binary && nchar=='\r') ) {
  275.             /* Replacing a char with a newline breaks the */
  276.             /* line in two, and is special. */
  277.             nchar = '\n';    /* convert \r to \n */
  278.             /* Save stuff necessary to undo it, by joining */
  279.             Uncurschar = Curschar-1;
  280.             addtobuff(Undobuff,'J','i',*Curschar,'\033',NULL);
  281.             /* Change current character. */
  282.             *Curschar = nchar;
  283.             /* We don't want to end up on the '\n' */
  284.             if ( Curschar > Filemem )
  285.                 Curschar--;
  286.             else if (Curschar < Fileend )
  287.                 Curschar++;
  288.         }
  289.         else {
  290.             /* Replacing with a normal character */
  291.             addtobuff(Undobuff,'r',*Curschar,NULL);
  292.             Uncurschar = Curschar;
  293.             /* Change current character. */
  294.             *Curschar = nchar;
  295.         }
  296.         /* Save stuff necessary to redo it */
  297.         addtobuff(Redobuff,'r',nchar,NULL);
  298.         updatescreen();
  299.         break;
  300.     case 'p':
  301.         putline(0);
  302.         break;
  303.     case 'P':
  304.         putline(1);
  305.         break;
  306.     case 'J':
  307.         for ( p=Curschar; *p!= '\n' && p<(Fileend-1) ; p++ )
  308.             ;
  309.         if ( p >= (Fileend-1) ) {
  310.             beep();
  311.             break;
  312.         }
  313.         Curschar = p;
  314.         delchar();
  315.         resetundo();
  316.         Uncurschar = Curschar;
  317.         addtobuff(Undobuff,'i','\n','\033',NULL);
  318.         addtobuff(Redobuff,'J',NULL);
  319.         updatescreen();
  320.         break;
  321.     case '.':
  322.         stuffin(Redobuff);
  323.         break;
  324.     case 'u':
  325.         if ( Uncurschar != NULL && *Undobuff != '\0' ) {
  326.             Curschar = Uncurschar;
  327.             stuffin(Undobuff);
  328.             *Undobuff = '\0';
  329.         }
  330.         if ( Undelchars > 0 ) {
  331.             Curschar = Uncurschar;
  332.             /* construct the next Undobuff and Redobuff, which */
  333.             /* will re-insert the characters we're deleting. */
  334.             p = Undobuff;
  335.             q = Redobuff;
  336.             *p++ = *q++ = 'i';
  337.             while ( Undelchars-- > 0 ) {
  338.                 *p++ = *q++ = *Curschar;
  339.                 delchar();
  340.             }
  341.             /* Finish constructing Uncursbuff, and Uncurschar */
  342.             /* is left unchanged. */
  343.             *p++ = *q++ = '\033';
  344.             *p = *q = '\0';
  345.             /* Undelchars has been reset to 0 */
  346.             updatescreen();
  347.         }
  348.         break;
  349.     default:
  350.         beep();
  351.         break;
  352.     }
  353. }
  354.  
  355. /*
  356.  * tabinout(inout,num)
  357.  *
  358.  * If inout==0, add a tab to the begining of the next num lines.
  359.  * If inout==1, delete a tab from the begining of the next num lines.
  360.  */
  361.  
  362. tabinout(inout,num)
  363. {
  364.     int ntodo = num;
  365.     char *savecurs, *p;
  366.  
  367.     beginline();
  368.     savecurs = Curschar;
  369.     while ( ntodo-- > 0 ) {
  370.         beginline();
  371.         if ( inout == 0 )
  372.             inschar('\t');
  373.         else {
  374.             if ( *Curschar == '\t' )
  375.                 delchar();
  376.         }
  377.         if ( ntodo > 0 ) {
  378.             if ( (p=nextline(Curschar)) != NULL )
  379.                 Curschar = p;
  380.             else
  381.                 break;
  382.         }
  383.     }
  384.     /* We want to end up where we started */
  385.     Curschar = savecurs;
  386.     updatescreen();
  387.     /* Construct re-do and un-do stuff */
  388.     sprintf(Redobuff,"%d%s",num,inout==0?">>":"<<");
  389.     resetundo();
  390.     Uncurschar = savecurs;
  391.     sprintf(Undobuff,"%d%s",num,inout==0?"<<":">>");
  392. }
  393.  
  394. startinsert(initstr)
  395. char *initstr;
  396. {
  397.     char *p, c;
  398.  
  399.     Insstart = Curschar;
  400.     Ninsert = 0;
  401.     Insptr = Insbuff;
  402.     for (p=initstr; (c=(*p++))!='\0'; )
  403.         *Insptr++ = c;
  404.     State = INSERT;
  405.     windrefresh();
  406. }
  407.  
  408. resetundo()
  409. {
  410.     Undelchars = 0;
  411.     *Undobuff = '\0';
  412.     Uncurschar = NULL;
  413. }
  414.